home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / sndhrdw / warpwarp.c < prev    next >
C/C++ Source or Header  |  2000-04-04  |  7KB  |  237 lines

  1. /****************************************************************************
  2.  *
  3.  * warpwarp.c
  4.  *
  5.  * sound driver
  6.  * juergen buchmueller <pullmoll@t-online.de>, jan 2000
  7.  *
  8.  ****************************************************************************/
  9.  
  10. #include <math.h>
  11. #include "driver.h"
  12.  
  13. #define CLOCK_16H    (18432000/3/2/16)
  14. #define CLOCK_1V    (18432000/3/2/384)
  15.  
  16. static INT16 *decay = NULL;
  17. static int channel;
  18. static int sound_latch = 0;
  19. static int music1_latch = 0;
  20. static int music2_latch = 0;
  21. static int sound_signal = 0;
  22. static int sound_volume = 0;
  23. static void *sound_volume_timer = NULL;
  24. static int music_signal = 0;
  25. static int music_volume = 0;
  26. static void *music_volume_timer = NULL;
  27. static int noise = 0;
  28.  
  29. static void sound_volume_decay(int param)
  30. {
  31.     if( --sound_volume < 0 )
  32.         sound_volume = 0;
  33. }
  34.  
  35. WRITE_HANDLER( warpwarp_sound_w )
  36. {
  37.     stream_update(channel,0);
  38.     sound_latch = data;
  39.     sound_volume = 0x7fff; /* set sound_volume */
  40.     noise = 0x0000;  /* reset noise shifter */
  41.  
  42.     /* faster decay enabled? */
  43.     if( sound_latch & 8 )
  44.     {
  45.         /*
  46.          * R85(?) is 10k, Rb is 0, C92 is 1uF
  47.          * charge time t1 = 0.693 * (R24 + Rb) * C57 -> 0.22176s
  48.          * discharge time t2 = 0.693 * (Rb) * C57 -> 0
  49.          * C90(?) is only charged via D17 (1N914), no discharge!
  50.          * Decay:
  51.          * discharge C90(?) (1uF) through R13||R14 (22k||47k)
  52.          * 0.639 * 15k * 1uF -> 0.9585s
  53.          */
  54.         if( sound_volume_timer )
  55.             timer_remove(sound_volume_timer);
  56.         sound_volume_timer = timer_pulse(TIME_IN_HZ(32768/0.9585), 0, sound_volume_decay);
  57.     }
  58.     else
  59.     {
  60.         /*
  61.          * discharge only after R93 (100k) and through the 10k
  62.          * potentiometerin the amplifier section.
  63.          * 0.639 * 110k * 1uF -> 7.0290s
  64.          * ...but this is not very realistic for the game sound :(
  65.          * maybe there _is_ a discharge through the diode D17?
  66.          */
  67.         if( sound_volume_timer )
  68.             timer_remove(sound_volume_timer);
  69. //        sound_volume_timer = timer_pulse(TIME_IN_HZ(32768/7.0290), 0, sound_volume_decay);
  70.         sound_volume_timer = timer_pulse(TIME_IN_HZ(32768/1.917), 0, sound_volume_decay);
  71.     }
  72. }
  73.  
  74. WRITE_HANDLER( warpwarp_music1_w )
  75. {
  76.     stream_update(channel,0);
  77.     music1_latch = data & 63;
  78. }
  79.  
  80. static void music_volume_decay(int param)
  81. {
  82.     if( --music_volume < 0 )
  83.         music_volume = 0;
  84. }
  85.  
  86. WRITE_HANDLER( warpwarp_music2_w )
  87. {
  88.     stream_update(channel,0);
  89.     music2_latch = data;
  90.     music_volume = 0x7fff;
  91.     /* fast decay enabled? */
  92.     if( music2_latch & 16 )
  93.     {
  94.         /*
  95.          * Ra (R83?) is 10k, Rb is 0, C92 is 1uF
  96.          * charge time t1 = 0.693 * (Ra + Rb) * C -> 0.22176s
  97.          * discharge time is (nearly) zero, because Rb is zero
  98.          * C95(?) is only charged via D17, not discharged!
  99.          * Decay:
  100.          * discharge C95(?) (10uF) through R13||R14 (22k||47k)
  101.          * 0.639 * 15k * 10uF -> 9.585s
  102.          * ...I'm sure this is off by one number of magnitude :/
  103.          */
  104.         if( music_volume_timer )
  105.             timer_remove(music_volume_timer);
  106. //        music_volume_timer = timer_pulse(TIME_IN_HZ(32768/9.585), 0, music_volume_decay);
  107.         music_volume_timer = timer_pulse(TIME_IN_HZ(32768/0.9585), 0, music_volume_decay);
  108.     }
  109.     else
  110.     {
  111.         /*
  112.          * discharge through R14 (47k),
  113.          * discharge C95(?) (10uF) through R14 (47k)
  114.          * 0.639 * 47k * 10uF -> 30.033s
  115.          */
  116.         if( music_volume_timer )
  117.             timer_remove(music_volume_timer);
  118. //        music_volume_timer = timer_pulse(TIME_IN_HZ(32768/30.033), 0, music_volume_decay);
  119.         music_volume_timer = timer_pulse(TIME_IN_HZ(32768/3.0033), 0, music_volume_decay);
  120.     }
  121.  
  122. }
  123.  
  124. static void warpwarp_sound_update(int param, INT16 *buffer, int length)
  125. {
  126.     static int vcarry = 0;
  127.     static int vcount = 0;
  128.     static int mcarry = 0;
  129.     static int mcount = 0;
  130.  
  131.     while (length--)
  132.     {
  133.         *buffer++ = (sound_signal + music_signal) / 2;
  134.  
  135.         /*
  136.          * The music signal is selected at a rate of 2H (1.536MHz) from the
  137.          * four bits of a 4 bit binary counter which is clocked with 16H,
  138.          * which is 192kHz, and is divided by 4 times (64 - music1_latch).
  139.          *    0 = 256 steps -> 750 Hz
  140.          *    1 = 252 steps -> 761.9 Hz
  141.          * ...
  142.          * 32 = 128 steps -> 1500 Hz
  143.          * ...
  144.          * 48 =  64 steps -> 3000 Hz
  145.          * ...
  146.          * 63 =   4 steps -> 48 kHz
  147.          */
  148.         mcarry -= CLOCK_16H / (4 * (64 - music1_latch));
  149.         while( mcarry < 0 )
  150.         {
  151.             mcarry += Machine->sample_rate;
  152.             mcount++;
  153.             music_signal = (mcount & ~music2_latch & 15) ? decay[music_volume] : 0;
  154.             /* override by noise gate? */
  155.             if( (music2_latch & 32) && (noise & 0x8000) )
  156.                 music_signal = decay[music_volume];
  157.         }
  158.  
  159.         /* clock 1V = 8kHz */
  160.         vcarry -= CLOCK_1V;
  161.         while (vcarry < 0)
  162.         {
  163.             vcarry += Machine->sample_rate;
  164.             vcount++;
  165.  
  166.             /* noise is clocked with raising edge of 2V */
  167.             if ((vcount & 3) == 2)
  168.             {
  169.                 /* bit0 = bit0 ^ !bit10 */
  170.                 if ((noise & 1) == ((noise >> 10) & 1))
  171.                     noise = (noise << 1) | 1;
  172.                 else
  173.                     noise = noise << 1;
  174.             }
  175.  
  176.             switch (sound_latch & 7)
  177.             {
  178.             case 0: /* 4V */
  179.                 sound_signal = (vcount & 0x04) ? decay[sound_volume] : 0;
  180.                 break;
  181.             case 1: /* 8V */
  182.                 sound_signal = (vcount & 0x08) ? decay[sound_volume] : 0;
  183.                 break;
  184.             case 2: /* 16V */
  185.                 sound_signal = (vcount & 0x10) ? decay[sound_volume] : 0;
  186.                 break;
  187.             case 3: /* 32V */
  188.                 sound_signal = (vcount & 0x20) ? decay[sound_volume] : 0;
  189.                 break;
  190.             case 4: /* TONE1 */
  191.                 sound_signal = !(vcount & 0x01) && !(vcount & 0x10) ? decay[sound_volume] : 0;
  192.                 break;
  193.             case 5: /* TONE2 */
  194.                 sound_signal = !(vcount & 0x02) && !(vcount & 0x20) ? decay[sound_volume] : 0;
  195.                 break;
  196.             case 6: /* TONE3 */
  197.                 sound_signal = !(vcount & 0x04) && !(vcount & 0x40) ? decay[sound_volume] : 0;
  198.                 break;
  199.             default: /* NOISE */
  200.                 /* QH of 74164 #4V */
  201.                 sound_signal = (noise & 0x8000) ? decay[sound_volume] : 0;
  202.             }
  203.  
  204.         }
  205.     }
  206. }
  207.  
  208. int warpwarp_sh_start(const struct MachineSound *msound)
  209. {
  210.     int i;
  211.  
  212.     decay = (INT16 *) malloc(32768 * sizeof(INT16));
  213.     if( !decay )
  214.         return 1;
  215.  
  216.     for( i = 0; i < 0x8000; i++ )
  217.         decay[0x7fff-i] = (INT16) (0x7fff/exp(1.0*i/4096));
  218.  
  219.     channel = stream_init("WarpWarp", 100, Machine->sample_rate, 0, warpwarp_sound_update);
  220.     return 0;
  221. }
  222.  
  223. void warpwarp_sh_stop(void)
  224. {
  225.     if( decay )
  226.         free(decay);
  227.     decay = NULL;
  228.     music_volume_timer = NULL;
  229.     sound_volume_timer = NULL;
  230. }
  231.  
  232. void warpwarp_sh_update(void)
  233. {
  234.     stream_update(channel,0);
  235. }
  236.  
  237.